[iOS][Swift] キーフレームアニメーションを作るRazzleDazzleの簡単な使い方
今回はSwift版のkeyframeアニメーション作れるRazzleDazzleというライブラリの簡単な使い方をご紹介したいと思います。 RazzleDazzleはJazzHandsというOvjective-Cのキーフレームアニメーション作れるライブラリのSwfit版になります。
キーフレームアニメーションといっても、どんなことが出来るのかイメージがわかない方はGithubページのデモGIFを見ると判りやすいです。 https://github.com/IFTTT/RazzleDazzle
今回は基本的な使い方をマスターするために、下記のような簡単なウォークスルーページを作りたいと思います。
開発環境
また、今回の開発環境は下記で実施しています。
Xcode | 7.3.1 |
---|---|
Swift | 2.2 |
CocoaPods | 1.0.0 |
ターゲットはiOS8.1、デバイスはiPhone、画面回転無しでProjectを作成しました。
導入
CocoaPodsで追加します。
use_frameworks! target "ターゲット名" do pod 'RazzleDazzle' end
実装
対象のViewControllerに対して
import RazzleDazzle
を追加して、
UIViewController
を
AnimatedPagingScrollViewController
に変更します。
import UIKit import RazzleDazzle class ViewController: AnimatedPagingScrollViewController {
AnimatedPagingScrollViewControllerはウォークスルーなどでよく見かける横にスクロールするUIScrollViewが用意されています。
ページ数の設定
スクロールのページ数の設定をします。今回は3ページとしました。下記コードを追加します。
// ページ数 override func numberOfPages() -> Int { return 3 }
ページとアニメーションの関係
RazzleDazzleのアニメーションはUIScrollViewの位置で変化を定義します。画面の左上の位置が基準になります。 スクロールの位置 = タイムライン のイメージです。
1ページ目を表示する時は0、2ページ目は1になります。0より大きく1未満の数字は1ページ目から2ページに遷移する途中の状態です。
背景色のアニメーション
まず最初に背景色を変更します。
override func viewDidLoad() { super.viewDidLoad() configureAnimations() } // アニメーションを設定する private func configureAnimations() { configureScrollView() } private func configureScrollView() { // 背景色のアニメーション let backgroundColorAnimation = BackgroundColorAnimation(view: scrollView) backgroundColorAnimation[-1] = UIColor.greenColor() backgroundColorAnimation[0] = UIColor.grayColor() backgroundColorAnimation[1] = UIColor.yellowColor() backgroundColorAnimation[1.3] = UIColor.brownColor() backgroundColorAnimation[2] = UIColor.redColor() backgroundColorAnimation[3] = UIColor.blueColor() animator.addAnimation(backgroundColorAnimation) }
let backgroundColorAnimation = BackgroundColorAnimation(view: scrollView)
で、scrollViewの背景アニメーションを作成します。
backgroundColorAnimation[0] = UIColor.grayColor()
これはは0の位置の時に灰色にするという定義です。今回は各ページ毎に色を変えてますが、背景色を変更するタイミングだけ定義すればOKです。
animator.addAnimation(backgroundColorAnimation)
で背景色の変更のアニメーションを登録します。
上記のサンプルコードの挙動は
1ページ目 :灰色
2ページ目 :黄色
3ページ目 :赤
2ページ目から3ページになる時に一旦茶色になってから変わる
1ページ目で左にスクロールしようとすると黄緑っぽい色になる
3ページ目で右にスクロールしようとすると青(紫?)っぽい色になる
となります。
パーツの配置
コード上で画像など配置するコンポーネントを追加していきます。
今回はそれぞれのページにテキスト用とイメージ用の画像を用意しました。
サンプルで利用している画像は下記からお借りしています。
http://flat-icon-design.com/
private let page1ImageView = UIImageView(image: UIImage(named: "page1")) private let page2ImageView = UIImageView(image: UIImage(named: "page2")) private let page3ImageView = UIImageView(image: UIImage(named: "page3")) private let text1ImageView = UIImageView(image: UIImage(named: "text1")) private let text2ImageView = UIImageView(image: UIImage(named: "text2")) private let text3ImageView = UIImageView(image: UIImage(named: "text3")) // ページ数 override func numberOfPages() -> Int { return 3 } override func viewDidLoad() { super.viewDidLoad() configureViews() configureAnimations() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // 画面にパーツを配置する private func configureViews () { contentView.addSubview(page1ImageView) contentView.addSubview(page2ImageView) contentView.addSubview(page3ImageView) contentView.addSubview(text1ImageView) contentView.addSubview(text2ImageView) contentView.addSubview(text3ImageView) }
contentView
に対して
addSubview
します。
この状態で実行すると、下図のように最初のページに固まってしまうので、表示するページの設定と制約等をつけます。
ページ指定と制約
// アニメーションを設定する private func configureAnimations() { configureScrollView() configurePage1() configurePage2() configurePage3() } private func configurePage1() { contentView.addConstraint(NSLayoutConstraint(item: page1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0)) contentView.addConstraint(NSLayoutConstraint(item: text1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0)) keepView(page1ImageView, onPage: 0) keepView(text1ImageView, onPage: 0) } private func configurePage2() { contentView.addConstraint(NSLayoutConstraint(item: page2ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0)) contentView.addConstraint(NSLayoutConstraint(item: text2ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0)) keepView(page2ImageView, onPage: 1) keepView(text2ImageView, onPage: 1) } private func configurePage3() { contentView.addConstraint(NSLayoutConstraint(item: page3ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0)) contentView.addConstraint(NSLayoutConstraint(item: text3ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0)) keepView(page3ImageView, onPage: 2) keepView(text3ImageView, onPage: 2) }
NSLayoutConstraintを使い位置を設定します。今回は上半分にイメージ画像、下半分にテキストの画像の簡単な構成なので、制約の内容は各ページ同じです。
keepView
でどのページに表示するかを定義します。
keepView(page1ImageView, onPage: 0)
は
page1ImageView
を最初のページ(左上が0)に表示します。
上記コードを実行すると以下の様な感じになります。
※ 一部背景色がどぎつい感じだったので変更してます
keepView の onPageについて
onPageに設定した値は正確にはX座標の中心点になります。keepView(page1ImageView, onPage: 0)の 0の部分を0.5に変更すると、 次のページとの中間部分が中心点になります。
フェードのアニメーションを入れる
keepView(page1ImageView, onPage: 0)
を
keepView(page1ImageView, onPages: [0, 1], atTimes: [0, 1])
に書き換えます。
onPagesは複数のページにまたがって表示したい時に配列で定義します。
atTimesはその配置するフレームを定義します。
上記のコードに変更して実行すると以下の挙動になります。
2ページ目の時も1ページ目の画像が残るようになりました。
次に2ページ目になるにつれ、画像がフェードアウトになるようにアニメーションを追加します。
private func configurePage1() { contentView.addConstraint(NSLayoutConstraint(item: page1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0)) contentView.addConstraint(NSLayoutConstraint(item: text1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0)) keepView(page1ImageView, onPages: [0, 1], atTimes: [0, 1]) keepView(text1ImageView, onPage: 0) let alphaAnimation = AlphaAnimation(view: page1ImageView) alphaAnimation[0] = 1 alphaAnimation[1] = 0 animator.addAnimation(alphaAnimation) }
AlphaAnimationを使うと透明度を変更することが出来ます。
alphaAnimation[0] = 1
上記コードは左上の位置が0(1ページ)の時はアルファ値が1、
alphaAnimation[1] = 0
左上の位置が1(2ページ)の時がアルファ値が0になるアニメーションになります。
同じように2ページめと3ページ目のイメージのアニメーションを修正します。
下記は今回の最終版のコードになります。
import UIKit import RazzleDazzle class ViewController: AnimatedPagingScrollViewController { private let page1ImageView = UIImageView(image: UIImage(named: "page1")) private let page2ImageView = UIImageView(image: UIImage(named: "page2")) private let page3ImageView = UIImageView(image: UIImage(named: "page3")) private let text1ImageView = UIImageView(image: UIImage(named: "text1")) private let text2ImageView = UIImageView(image: UIImage(named: "text2")) private let text3ImageView = UIImageView(image: UIImage(named: "text3")) // ページ数 override func numberOfPages() -> Int { return 3 } override func viewDidLoad() { super.viewDidLoad() configureViews() configureAnimations() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // 画面にパーツを配置する private func configureViews () { contentView.addSubview(page1ImageView) contentView.addSubview(page2ImageView) contentView.addSubview(page3ImageView) contentView.addSubview(text1ImageView) contentView.addSubview(text2ImageView) contentView.addSubview(text3ImageView) } // アニメーションを設定する private func configureAnimations() { configureScrollView() configurePage1() configurePage2() configurePage3() } private func configureScrollView() { // 背景色のアニメーション let backgroundColorAnimation = BackgroundColorAnimation(view: scrollView) backgroundColorAnimation[-1] = UIColor.greenColor() backgroundColorAnimation[0] = UIColor.lightGrayColor() backgroundColorAnimation[1] = UIColor.yellowColor() backgroundColorAnimation[1.3] = UIColor.brownColor() backgroundColorAnimation[2] = UIColor.orangeColor() backgroundColorAnimation[3] = UIColor.blueColor() animator.addAnimation(backgroundColorAnimation) } private func configurePage1() { contentView.addConstraint(NSLayoutConstraint(item: page1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0)) contentView.addConstraint(NSLayoutConstraint(item: text1ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0)) keepView(page1ImageView, onPages: [0, 1], atTimes: [0, 1]) keepView(text1ImageView, onPage: 0) let alphaAnimation = AlphaAnimation(view: page1ImageView) alphaAnimation[0] = 1 alphaAnimation[1] = 0 animator.addAnimation(alphaAnimation) } private func configurePage2() { contentView.addConstraint(NSLayoutConstraint(item: page2ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0)) contentView.addConstraint(NSLayoutConstraint(item: text2ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0)) keepView(page2ImageView, onPages: [0, 1, 2], atTimes: [0, 1, 2]) keepView(text2ImageView, onPage: 1) let alphaAnimation = AlphaAnimation(view: page2ImageView) alphaAnimation[0] = 0 alphaAnimation[1] = 1 alphaAnimation[2] = 0 animator.addAnimation(alphaAnimation) } private func configurePage3() { contentView.addConstraint(NSLayoutConstraint(item: page3ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 0.65, constant: 0)) contentView.addConstraint(NSLayoutConstraint(item: text3ImageView, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.65, constant: 0)) keepView(page3ImageView, onPages: [1, 2], atTimes: [1, 2]) keepView(text3ImageView, onPage: 2) let alphaAnimation = AlphaAnimation(view: page3ImageView) alphaAnimation[1] = 0 alphaAnimation[2] = 1 animator.addAnimation(alphaAnimation) } }
さいごに
今回は単純にbackgroundColorとalphaしか使いませんでしたが、他にも色々なプロパティのアニメーションをすることが出来ます。 色々と試してみると楽しいかもしれません。